/* 
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 * 
 *     http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.apache.harmony.javax.naming;

import java.util.Arrays;

/**
 * A <code>BinaryRefAddr</code> refers to an address which is represented by a
 * binary address.
 */
public class BinaryRefAddr extends RefAddr {

	private static final long serialVersionUID = -3415254970957330361L;

	/**
	 * The buffer for the binary address itself.
	 * 
	 * @serial
	 */
	private final byte[] buf;

	/**
	 * Constructs a <code>BinaryRefAddr</code> using the specified address type
	 * and the full details of the supplied byte array.
	 * 
	 * @param type
	 *            the address type which cannot be null
	 * @param address
	 *            the address itself which cannot be null
	 */
	public BinaryRefAddr(String type, byte[] address) {
		this(type, address, 0, address.length);
	}

	/**
	 * Constructs a <code>BinaryRefAddr</code> using the specified address type
	 * and part of the supplied byte array. The number of bytes to be taken is
	 * specified by <code>size</code>. Additionally these bytes are taken from a
	 * starting point specified by <code>index</code>.
	 * 
	 * @param type
	 *            the address type. It cannot be null.
	 * @param address
	 *            the address itself. It cannot be null.
	 * @param index
	 *            the starting point to copy bytes from. It must be greater than
	 *            or equal to zero and must be less than or equal to the size of
	 *            the byte array.
	 * @param size
	 *            the number of bytes to copy. It must be greater than or equal
	 *            to zero and must be less than or equal to the size of the byte
	 *            array less the starting position.
	 * @throws ArrayIndexOutOfBoundsException
	 *             If <code>size</code> or <code>index</code> does not meet the
	 *             constraints.
	 */
	public BinaryRefAddr(String type, byte[] address, int index, int size) {
		super(type);
		buf = new byte[size];
		System.arraycopy(address, index, buf, 0, size);
	}

	/**
	 * Returns true if this address is equal to the supplied object
	 * <code>o</code>. They are considered equal if the address types are equal
	 * and the data in the buffers is of the same length and contains the same
	 * bytes.
	 * 
	 * @param o
	 *            the object to compare with
	 * @return true if this address is equal to <code>o</code>, otherwise false
	 */
	@Override
	public boolean equals(Object o) {
		if (o instanceof BinaryRefAddr) {
			final BinaryRefAddr a = (BinaryRefAddr) o;
			return addrType.equals(a.addrType) && Arrays.equals(buf, a.buf);
		}
		return false;
	}

	/**
	 * Gets the content of this address.
	 * 
	 * @return an array of bytes containing the address. It cannot be null.
	 */
	@Override
	public Object getContent() {
		return buf;
	}

	/**
	 * Returns the hashcode of this address. The result is the hashcode of the
	 * address type added to each byte from the data buffer.
	 * 
	 * @return the hashcode of this address
	 */
	@Override
	public int hashCode() {
		int i = addrType.hashCode();

		for (final byte element : buf) {
			i += element;
		}
		return i;
	}

	/**
	 * Returns the string representation of this address. The string includes
	 * the address type and a maximum of 128 bytes address content expressed in
	 * hexadecimal form.
	 * 
	 * @return the string representation of this address
	 */
	@Override
	public String toString() {
		String s = "The type of the address is: " //$NON-NLS-1$
				+ addrType + "\nThe content of the address is: "; //$NON-NLS-1$
		final int max = buf.length > 128 ? 128 : buf.length;

		for (int i = 0; i < max; i++) {
			s += Integer.toHexString(buf[i]) + " "; //$NON-NLS-1$
		}
		s = s.substring(0, s.length() - 1) + "\n"; //$NON-NLS-1$

		return s;
	}

}
